package com.tansice.jwt.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.tansice.jwt.config.JWTConfig;
import com.tansice.jwt.service.JWTService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class JWTServiceImpl implements JWTService {
    private static Logger logger = LoggerFactory.getLogger(JWTServiceImpl.class);
    @Autowired
    JWTConfig jwtConfig;


    @Override
    public String createJWT(Map<String, String> data) {
        //Header信息
        Map<String, Object> headerClaims = new HashMap<>();
        //类型
        headerClaims.put("typ", "JWT");
        //算法名称
        headerClaims.put("alg", "HS256");
        //密钥
        JWTCreator.Builder builder = JWT.create().withHeader(headerClaims);
        Set<Map.Entry<String, String>> entrySet = data.entrySet();
        //自定义Payload字段
        for (Map.Entry<String, String> entry : entrySet) {
            builder.withClaim(entry.getKey(), entry.getValue());
        }
        Calendar expiredTime = Calendar.getInstance();
        expiredTime.add(Calendar.SECOND, jwtConfig.getExpiredTime());
        try {
            String token = builder
                    //签发人
                    .withIssuer("Trial")
                    //签发时间
                    .withIssuedAt(new Date())
                    // 过期时间
                    .withExpiresAt(expiredTime.getTime())
                    // 创建时间
                    .withIssuedAt(new Date())
                    // 签名
                    .sign(Algorithm.HMAC256(jwtConfig.getJwtSecret()));
            logger.debug("create token:{}", token);
            return token;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException("JWT签名错误！" + e.getMessage(), e);
        }
    }

    @Override
    public Map<String, Claim> verfiyJWT(String token) {
        JWTVerifier verifier = null;
        try {
            verifier = JWT.require(Algorithm.HMAC256(jwtConfig.getJwtSecret())).build();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException("jwt操作失败", e);
        }

        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        } catch (TokenExpiredException e) {
            throw new RuntimeException("jwt已过期", e);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException("jwt验证错误", e);
        }
        Map<String, Claim> claimMap = jwt.getClaims();
        String playload = jwt.getPayload();
        logger.info("playload :{}",playload);
        return claimMap;
    }
}
